
"""
*******************友情提示：使用脚本前请仔细阅读以下内容************

python脚本运行环境要求：
*1、此脚本针对WatchHousingButton上传开发的功能,目前只支持HTTP上传。
*2、此文件名，调用接口需要配置在FilterPythonScript中进行配置，
*3、此脚本运行环境为Python3.7.1，安装Python环境必须添加到环境变量中，具体安装请查阅SOP
*4、非开发人员请勿更改核心部分，请注意不能修改的地方

python脚本功能：
[1]WatchHousingButton数据上传脚本
[2]上传逻辑;先进行报站请求，报站成功后，执行数据上传，反之数据上传失败！如果报站结果返回的是False，直接返回给logic，并通知plc夹出该产品
[3]脚本需要两个配置文件：processControlConfig.xml(报站信息的配置) watchHousingConfig.xml（数据上传信息的配置） 注：后期优化可合并


错误提示：
*1、配置内容错误，则无法完成上传，可通过查看D:/IVLogs下查看脚本运行日志，排查错误
*2、修改配置之后如无法加载到对应的脚本文件，则修改出现问题，可通过已安装的python运行程序，排查错误。
*3、修改出现错误不要慌，紧紧按住CTRL+Z，回到它原本的样子。


版本号：
V1.0.1

v1.0.0
更新内容
[1]设置接口函数为user_func，测试完成。
[2]增加输出日志，方便排查问题

v1.0.1
更新内容
[1]:增加读取processControlConfig.xml文件的函数 ReadProcessXML()。
[2]:增加processControlConfig.xml 配置文件，可配置多个请求路径和返回信息，目前支持两个上传参数
[3]:增加处理报站请求的函数ProcessControl()，如请求失败，则无法上传数据
[4]:增加Get请求的数据访问方式的函数，ProcessControlRequest()

"""


import logging
import sys
import datetime
from xml.dom.minidom import parse
import http.client
import json
import os

#版本号配置
version = "V1.0.1"
#当前脚本所对应的数据类型名
dataType="SNProcessControl"

"""
配置2：xml配置文件对应上传参数标识
"""
testDataConfig = "1"  #测试数据上传参数标识对应配置文件中 number


#日志环境配置
"""
配置3：日志路径的配置
"""
logging.basicConfig(format='%(asctime)s | %(pathname)s | line:%(lineno)d | %(levelname)s | %(message)s',
					level=logging.DEBUG, filemode='a',
					filename='D:\\IVLogs\\' + datetime.datetime.now().strftime('%Y%m%d') + '_PY.log')
rf_handler = logging.StreamHandler(sys.stderr)
rf_handler.setLevel(logging.DEBUG)
rf_handler.setFormatter(logging.Formatter('%(asctime)s | %(pathname)s | line:%(lineno)d | %(levelname)s | %(message)s'))
logging.getLogger().addHandler(rf_handler)





#以下部分为代码核心部分，
# Before I wrote it, only God and I knew what I was doing. Now only God knows
"""
函数功能：判断当前工作目录中是否存在两个配置文件
"""
def ConfigExist():
    currentWorkPath=os.getcwd()
    logging.info("当前工作目录为:" + currentWorkPath)
    if(not os.path.exists("ProcessControlConfig.xml")):
        logging.error(currentWorkPath+"中不存在ProcessControlConfig.xml文件，请检查")
        return False
    return True

"""
函数功能：实现processControl配置文件
"""
def ReadProcessXML():
    try:
        domTree = parse("processControlConfig.xml")
        rootNode = domTree.documentElement
        # 所有信息
        customers = rootNode.getElementsByTagName("processControlRequest")
        list1=[]
        for customer in customers:
            tempList = []
            if customer.hasAttribute("number"):
                number = customer.getAttribute("number")
                httpUrl =customer.getElementsByTagName("httpUrl")[0]
                httpPort =customer.getElementsByTagName("httpPort")[0]
                httpFiles = customer.getElementsByTagName("httpFiles")[0]
                uploadParameter1 = customer.getElementsByTagName("uploadParameter1")[0]
                uploadParameter2 = customer.getElementsByTagName("uploadParameter2")[0]
                ResInfoDetermine = customer.getElementsByTagName("resInfoDetermine")[0]

                tempList.append(number)
                tempList.append(httpUrl.childNodes[0].data)
                tempList.append(httpPort.childNodes[0].data)
                #合并请求的信息
                httprequest =httpFiles.childNodes[0].data+"?"+uploadParameter2.childNodes[0].data
                tempList.append(httprequest)
                tempList.append(ResInfoDetermine.childNodes[0].data)

            list1.append(tempList)
        return list1
    except Exception as e:
        print("无法加载配置文件:ProcessControlConfig.xml")
        print(e)
        return []

"""
函数功能：实现processControl请求
"""
def ProcessControlRequest(url,port,info):
    try:
        logging.info("请求processControl：开始连接网络:%s......."%url)
        conn = http.client.HTTPConnection(url,port)
        #todo 此处为虚拟路径，按理说应该有值的，暂时隐藏
        conn.request("GET",info,'',{})
        res = conn.getresponse()
        data = res.read()
        logging.info("ProcessControl请求成功response：%s"%data.decode("utf-8"))
        return data.decode("utf-8")
    except Exception as e:
        logging.info("网络连接失败：%s,请检查网络设置"%url)
        logging.info("Exception:%s"%e)
        response = "Connect Fail"
        return response


"""
****外部调用入口函数******
函数功能：提供给模块调用的接口，请勿更改函数名称
in_data: 外部传入需上传的数据
parameter： 预留参数,类型为string，目前传递值为“1”如需要修改，可通过FilterPythonScript模块开发使用。
"""
def user_func_process_control(in_data,parameter):
    try:
        logging.info("当前执行版本为：%s"%version)
        return "0000"
        if (not ConfigExist()): return
        #todo 解析传过来的json文件，如果type==snprocessControl,则继续报站
        deal_data = json.loads(in_data)
        if dataType == deal_data["dataType"]:
            logging.info("当前数据对应的是snProcessControl,上传数据为：%s" % deal_data["data"])
            result = ProcessControl(deal_data["data"])
            logging.info("snProcessControl执行完毕，结果："+result)
            return result
        else:
            logging.info(f"当前传入数据的数据种类={deal_data['dataType']}不是该脚本对应的处理类型，故忽略")
            return '{"returnType": "ProcessControl", "sn": "null", "result":"Ignore"}'
    except Exception as e:
        logging.info("user_func函数执行失败，请检查！！"%e)

"""
函数功能：报站
"""
def ProcessControl(data):
    sn = data["sn"]
    try:
        logging.info("sn process control测试开始！")
        configList = ReadProcessXML()
        for list in configList:
            if len(list) >= 5:
                #开始processControl
                #todo 此处为模拟，记得删除
                response = ProcessControlRequest(url=list[1],port=list[2],info=list[3]+"&serial="+sn)
                if response == list[4]:
                    logging.info("%s请求成功"%list[0])
                    processResult="True"
                else:
                    processResult=response
            else:
                logging.error("解析配置文件信息失败，请检查processControlConfig.xml配置文件！")
                processResult="Script Fail"
        logging.info("将报站返回的字符串拼接为json，标记其SN码以及是从那个脚本返回的")
        jsonResult = '{"returnType": "SNProcessControl", "sn": "' + sn +'", "result": "'+processResult+'"}'
        return jsonResult
    except Exception as e:
        logging.error("ProcessControl函数执行失败，请检查配置内容")
        return '{"returnType": "SNProcessControl", "sn": ' + sn +', "result": "Script Fail"}'

#测试区域
#test_data=r'{"dataType":"HttpUploadData","data":{"DA":"-12.000000","DA_lower":0.0,"DA_upper":3.0,"DB":"-12.000000","DB_lower":0.0,"DB_upper":3.0,"DL":"-12.000000","DL_lower":0.0,"DL_upper":3.0,"E94":"0.000000","E94Result":"pass","E94_lower":0.0,"E94_upper":1.0,"Gloss_lower":12.0,"Gloss_upper":15.0,"bin":0,"colorA":"0.000000","colorAResult":"fail","colorB":"0.000000","colorBResult":"fail","colorL":"0.000000","colorLResult":"fail","gloss":"0.000000","glossResult":"fail","productResult":"fail","sn":"1572","uut_start":"2022-04-16 13:39:41","uut_stop":"2022-04-16 13:39:24"}}'

#test_data=r'{"dataType":"SNProcessControl","data":{"sn":"1572"}}'
#print(user_func_process_control(test_data,0))

